using DimensionsHelper.Common.Contracts;
using DimensionsHelper.Common.Contracts.TableFormatter;
using DimensionsHelper.Common.Contracts.TableFormatter.Options;
using DimensionsHelper.Common.TableFormatter;

namespace DimensionsHelper.Client.ViewModels.CsvFormatter;

public partial class MenuOptionsViewModel : RangeStyleOptionsViewModel, IProjectOption<MenuOptions>
{

    [ObservableProperty]
    private bool _buildMenu;


    [ObservableProperty]
    private string _backText = TableFormatterDefaultValues.MenuBackText;
    
    
    [ObservableProperty]
    private string _baseContentFormat = TableFormatterDefaultValues.BaseContentFormat;


    [ObservableProperty]
    private int _baseValueColumn = TableFormatterDefaultValues.BaseColumn;
    
    
    [ObservableProperty]
    private int _emptyRowsFollowSheetLabel = TableFormatterDefaultValues.EmptyRowsFollowSheetLabel;


    [ObservableProperty]
    private bool _hideNumber;


    [ObservableProperty]
    private string _indexSheetName = TableFormatterDefaultValues.MenuIndexSheetName;
    
    
    [ObservableProperty]
    private string _linkSheetName = TableFormatterDefaultValues.MenuLinkSheetName;


    [ObservableProperty]
    private string _linkSheetLabel = TableFormatterDefaultValues.MenuLinkSheetLabel;
    
    
    [ObservableProperty]
    private MenuType _menuBuildType;


    [ObservableProperty]
    private bool _mergeSection;


    [ObservableProperty]
    private bool _showBase;


    [ObservableProperty]
    private bool _showMultiBase;


    [ObservableProperty]
    private bool _showMultiBaseInOneCell;


    [ObservableProperty]
    private bool _showSection;


    public MenuOptionsViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
    {
        HyperlinkStyle = serviceProvider.GetRequiredService<TableStyleOptionsViewModel>().HyperlinkStyle;
        SectionStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        BaseStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        LinkSheetLabelStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        BackTextStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        SheetLabelStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        TableLabelStyle = serviceProvider.GetRequiredService<RangeStyleOptionsViewModel>();
        _currentRange = this;

        PropertyChanged += OnRangeOptionsPropertyChanged;
    }


    private void SetRangesValue<T>(Action<RangeStyleOptionsViewModel, T> setter, T value)
    {
        setter(SectionStyle, value);
        setter(BaseStyle, value);
        setter(LinkSheetLabelStyle, value);
        setter(BackTextStyle, value);
        setter(SheetLabelStyle, value);
        setter(TableLabelStyle, value);
    }


    private void OnRangeOptionsPropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case nameof(FontFamily):
            {
                SetRangesValue(static (range, value) => range.FontFamily = value, FontFamily);
                break;
            }

            case nameof(FontSize):
            {
                SetRangesValue(static (range, value) => range.FontSize = value, FontSize);
                break;
            }

            case nameof(FontColorBrush):
            {
                SetRangesValue(static (range, value) => range.FontColorBrush = value, FontColorBrush);
                break;
            }

            case nameof(Bold):
            {
                SetRangesValue(static (range, value) => range.Bold = value, Bold);
                break;
            }

            case nameof(Italic):
            {
                SetRangesValue(static (range, value) => range.Italic = value, Italic);
                break;
            }

            case nameof(Underlined):
            {
                SetRangesValue(static (range, value) => range.Underlined = value, Underlined);
                break;
            }

            case nameof(UnderLineType):
            {
                SetRangesValue(static (range, value) => range.UnderLineType = value, UnderLineType);
                break;
            }

            case nameof(HAlign):
            {
                SetRangesValue(static (range, value) => range.HAlign = value, HAlign);
                break;
            }

            case nameof(VAlign):
            {
                SetRangesValue(static (range, value) => range.VAlign = value, VAlign);
                break;
            }

            case nameof(AddHorizontalBorder):
            {
                SetRangesValue(static (range, value) => range.AddHorizontalBorder = value, AddHorizontalBorder);
                break;
            }

            case nameof(AddVerticalBorder):
            {
                SetRangesValue(static (range, value) => range.AddVerticalBorder = value, AddVerticalBorder);
                break;
            }

            case nameof(AddAroundBorder):
            {
                SetRangesValue(static (range, value) => range.AddAroundBorder = value, AddAroundBorder);
                break;
            }
        }
    }
    
    
    [ObservableProperty]
    private RangeStyleOptionsViewModel _currentRange;
    
    public FontStyleOptionsViewModel HyperlinkStyle { get; }
    
    public RangeStyleOptionsViewModel SectionStyle { get; }
    
    public RangeStyleOptionsViewModel BaseStyle { get; }
    
    public RangeStyleOptionsViewModel LinkSheetLabelStyle { get; }
    
    public RangeStyleOptionsViewModel BackTextStyle { get; }
    
    public RangeStyleOptionsViewModel SheetLabelStyle { get; }
    
    public RangeStyleOptionsViewModel TableLabelStyle { get; }


    public bool TryWriteOption(MenuOptions target)
    {
        target.BuildMenu = BuildMenu;
        target.MenuType = MenuBuildType; 
        target.LinkSheetName = LinkSheetName;
        target.LinkSheetLabel = LinkSheetLabel;
        target.IndexSheetName = IndexSheetName;
        target.BackText = BackText;
        target.BaseValueColumn = BaseValueColumn;
        target.BaseContentFormat = BaseContentFormat;
        target.EmptyRowsFollowSheetLabel = EmptyRowsFollowSheetLabel;
        target.ShowSection = ShowSection;
        target.ShowBase = ShowBase;
        target.ShowMultiBase = ShowMultiBase;
        target.ShowMultiBaseInOneCell = ShowMultiBaseInOneCell;
        target.HideNumber = HideNumber;
        target.MergeSection = MergeSection;
        
        return SectionStyle.TryWriteOption(target.SectionStyleOptions)
            && BaseStyle.TryWriteOption(target.BaseStyleOptions)
            && LinkSheetLabelStyle.TryWriteOption(target.LinkSheetLabelStyleOptions)
            && BackTextStyle.TryWriteOption(target.BackStyleOptions)
            && SheetLabelStyle.TryWriteOption(target.SheetLabelStyleOptions)
            && TableLabelStyle.TryWriteOption(target.TableLabelStyleOptions);
    }

    public void LoadOption(MenuOptions source)
    {
        BuildMenu = source.BuildMenu;
        MenuBuildType = source.MenuType;
        LinkSheetName = source.LinkSheetName;
        LinkSheetLabel = source.LinkSheetLabel;
        IndexSheetName = source.IndexSheetName;
        BackText = source.BackText;
        BaseValueColumn = source.BaseValueColumn;
        BaseContentFormat = source.BaseContentFormat;
        EmptyRowsFollowSheetLabel = source.EmptyRowsFollowSheetLabel;
        ShowSection = source.ShowSection;
        ShowBase = source.ShowBase;
        ShowMultiBase = source.ShowMultiBase;
        ShowMultiBaseInOneCell = source.ShowMultiBaseInOneCell;
        HideNumber = source.HideNumber;
        MergeSection = source.MergeSection;
        
        SectionStyle.LoadOption(source.SectionStyleOptions);
        BaseStyle.LoadOption(source.BaseStyleOptions);
        LinkSheetLabelStyle.LoadOption(source.LinkSheetLabelStyleOptions);
        BackTextStyle.LoadOption(source.BackStyleOptions);
        SheetLabelStyle.LoadOption(source.SheetLabelStyleOptions);
        TableLabelStyle.LoadOption(source.TableLabelStyleOptions);
    }
}